﻿using System;
using System.Diagnostics.Contracts;

namespace CodePlex.Diagnostics.Contracts.Conditions
{
	public static partial class Condition
	{
		[Pure]
		public static bool IsGreaterThan<T>(this T value, T lowerBound) where T : IComparable<T>
		{
			Contract.Requires(!value.IsNull());

			return value.CompareTo(lowerBound) > 0;
		}

		[Pure]
		public static bool IsLessThan<T>(this T value, T upperBound) where T : IComparable<T>
		{
			Contract.Requires(!value.IsNull());

			return value.CompareTo(upperBound) < 0;
		}

		[Pure]
		public static bool IsGreaterThanOrEqual<T>(this T value, T lowerBound) where T : IComparable<T>
		{
			Contract.Requires(!value.IsNull());

			return value.CompareTo(lowerBound) >= 0;
		}

		[Pure]
		public static bool IsLessThanOrEqual<T>(this T value, T upperBound) where T : IComparable<T>
		{
			Contract.Requires(!value.IsNull());

			return value.CompareTo(upperBound) <= 0;
		}
		
		[Pure]
		public static bool IsInRange<T>(this T value, T lowerBound, T upperBound) where T : IComparable<T>
		{
			Contract.Requires(!value.IsNull());

			return value.CompareTo(lowerBound) >= 0 && value.CompareTo(upperBound) <= 0;
		}

		[Pure]
		public static bool IsInRange<T>(this T value, T lowerBound, bool lowerBoundExclusive, T upperBound, bool upperBoundExclusive) 
			where T : IComparable<T>
		{
			Contract.Requires(!value.IsNull());

			return lowerBoundExclusive ? value.CompareTo(lowerBound) > 0 : value.CompareTo(lowerBound) >= 0 &&
				   upperBoundExclusive ? value.CompareTo(upperBound) < 0 : value.CompareTo(upperBound) <= 0;
		}
	}
}
